package com.iakuil.mvp.mp.controller;

import com.iakuil.mvp.mp.common.BaseController;
import com.iakuil.mvp.mp.common.constant.RespCode;
import com.iakuil.mvp.mp.common.domain.Resp;
import com.iakuil.mvp.mp.dao.entity.MpUserInfo;
import com.iakuil.mvp.mp.dto.DecryptDataParam;
import com.iakuil.mvp.mp.dto.LoginSucc;
import com.iakuil.mvp.mp.dto.MpUserProfileEdit;
import com.iakuil.mvp.mp.dto.wx.MpPhoneData;
import com.iakuil.mvp.mp.dto.wx.MpUserInfoDTO;
import com.iakuil.mvp.mp.dto.wx.SessionKey;
import com.iakuil.mvp.mp.security.WxCodeToken;
import com.iakuil.mvp.mp.service.MpUserInfoService;
import com.iakuil.mvp.mp.service.WxApiService;
import com.iakuil.mvp.mp.service.WxTokenMgr;
import com.iakuil.toolkit.BeanUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

@Api(value = "小程序接口", tags = {"小程序相关接口"})
@Slf4j
@RestController
@RequestMapping("/mp/user/")
public class MpUserController extends BaseController {

    private final WxApiService wxApiService;

    private final WxTokenMgr wxTokenMgr;

    private final MpUserInfoService mpUserInfoService;

    public MpUserController(WxApiService wxApiService, WxTokenMgr wxTokenMgr, MpUserInfoService mpUserInfoService) {
        this.wxApiService = wxApiService;
        this.wxTokenMgr = wxTokenMgr;
        this.mpUserInfoService = mpUserInfoService;
    }

    @ApiOperation(value = "用户信息", notes = "获取用户信息。")
    @GetMapping(value = "/userInfo")
    public Resp<MpUserInfo> getUserInfo() {
        MpUserInfo loginUser = getLoginUser();
        if (loginUser == null) {
            loginUser = new MpUserInfo();
            loginUser.setOpenId("0");
            loginUser.setNickName("游客");
        }
        return ok(loginUser);
    }

    @ApiOperation(value = "用户登录", notes = "小程序用户登录，并返回openid。")
    @PostMapping(value = "/login")
    public Resp<LoginSucc> login(@RequestParam String code) {
        SessionKey sk = wxTokenMgr.getSessionKeyByCode(code);
        if (sk == null || sk.getOpenId() == null) {
            return fail(RespCode.UNAUTHORIZED);
        }

        String openId = sk.getOpenId();
        // 如果数据库中存在此openid记录，则认为登录成功
        SecurityUtils.getSubject().login(new WxCodeToken(openId));
        return ok(new LoginSucc(openId, SecurityUtils.getSubject().getSession().getId().toString()));
    }

    @ApiOperation(value = "修改用户信息", notes = "修改用户信息（仅能修改自己的）。")
    @PostMapping(value = "/modify")
    public Resp<?> modifyUserInfo(@Validated @RequestBody MpUserProfileEdit param) {
        MpUserInfo loginUser = getLoginUser();
        if (loginUser == null) {
            return fail(RespCode.UNAUTHORIZED);
        }
        MpUserInfo entity = BeanUtils.copy(param, MpUserInfo.class);
        entity.setOpenId(loginUser.getOpenId());
        return ok(mpUserInfoService.modify(entity));
    }

    @ApiOperation(value = "解密手机数据", notes = "解密小程序手机数据，未注册用户自动注册。")
    @PostMapping(value = "/decryptPhone")
    Resp<MpPhoneData> decryptPhone(@ApiParam(value = "加密数据及参数") @Validated @RequestBody DecryptDataParam params) {
        return ok(wxApiService.decryptPhone(params));
    }

    @ApiOperation(value = "解密用户数据", notes = "解密小程序用户数据，未注册用户自动注册。")
    @PostMapping(value = "/decryptUserInfo")
    Resp<MpUserInfoDTO> decryptUserInfo(@ApiParam(value = "加密数据及参数") @Validated @RequestBody DecryptDataParam params) {
        return ok(wxApiService.decryptUserInfo(params));
    }
}
